﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading.Tasks;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Drawing.Imaging;
using System.IO;
using System.Threading;
using System.Collections;

namespace ChatRoom
{
    public partial class frmChat : Form
    {
        Hashtable clients = new Hashtable();
        System.Net.Sockets.TcpClient clientSocket = new System.Net.Sockets.TcpClient();
        NetworkStream serverStream = default(NetworkStream);
        string readData = null;
        bool connected = false;
        String fn;
        public bool con = false;
        Image img;
        Socket s1;
        string ip;
        int port;
        string name;
        int Level;

        public frmChat(string IP, int Port, string userName, int level)
        {
            InitializeComponent();
            this.FormBorderStyle = FormBorderStyle.FixedToolWindow;
            this.MaximizeBox = false;
            this.MinimizeBox = false;
            picLogo.ImageLocation = "F:/My Documents/Logo.png";
            ip = IP;
            port = Port;
            name = userName;
            Level = level;
            lblUser.Text = name;
            tmrUsers.Start();
            if(Level == 1)
            {
                txtAdmin.Show();
            }
            connect();
        }

        //connects to the server
        private void connect()
        {
            readData = "Conected to Chat Server ...";
            msg();
            clientSocket.Connect(ip, port);
            serverStream = clientSocket.GetStream();
            connected = true;

            byte[] outStream = System.Text.Encoding.ASCII.GetBytes(name + "$");
            serverStream.Write(outStream, 0, outStream.Length);
            serverStream.Flush();

            Thread ctThread = new Thread(getMessage);
            ctThread.Start();
            btnDisconnect.Enabled = true;
            btnMessage.Enabled = true;
        }
        private void frmChat_Load(object sender, EventArgs e)
        {
            
        }
        private void getMessage()
        {
            //retreives messages sent
            while (connected == true)
            {
                try
                {
                    serverStream = clientSocket.GetStream();
                    int buffSize = 0;
                    byte[] inStream = new byte[10025];
                    buffSize = clientSocket.ReceiveBufferSize;
                    serverStream.Read(inStream, 0, buffSize);
                    string returndata = System.Text.Encoding.ASCII.GetString(inStream);
                    readData = "" + returndata;
                    msg();
                }
                catch
                {

                }
            }
        }
        private void msg()
        {
            //sends messages
            if (this.InvokeRequired)
                this.Invoke(new MethodInvoker(msg));
            else
                txtMessageBox.Text = txtMessageBox.Text + Environment.NewLine + " >> " + readData;
        }

        //sends message when
        private void btnMessage_Click(object sender, EventArgs e)
        {
            try
            {
                byte[] outStream = System.Text.Encoding.ASCII.GetBytes(txtMessage.Text + "$");
                serverStream.Write(outStream, 0, outStream.Length);
                serverStream.Flush();
                txtMessage.Clear();
            }
            catch
            {
                MessageBox.Show("Please be connected to a server when attempting to send messages");
            }
        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            Environment.Exit(Environment.ExitCode);
        }

        //disconnects from the server
        private void btnDisconnect_Click(object sender, EventArgs e)
        {
            connected = false;
            try
            {
                byte[] outStream = System.Text.Encoding.ASCII.GetBytes(txtMessage.Text + "$");
                serverStream.Write(outStream, 0, outStream.Length);
                serverStream.Flush();
                serverStream.Dispose();
            }
            catch
            {

            }
            connected = false;
            clientSocket.Close();
            readData = "Disconnected from Server";
            lblLogged.Text = "Logged Out";
            msg();
        }

        //sends message when enter pushed while in message box
        private void txtMessage_KeyDown(object sender, KeyEventArgs e)
        {
            if (connected == true)
            {
                if (e.KeyCode == Keys.Return)
                {
                    byte[] outStream = System.Text.Encoding.ASCII.GetBytes(txtMessage.Text + "$");
                    serverStream.Write(outStream, 0, outStream.Length);
                    serverStream.Flush();
                    txtMessage.Clear();
                }
            }
        }

        private void startAdmin()
        {
            Admin f2 = new Admin();
            f2.MdiParent = this.ParentForm; //this refers to f1's parent, the MainForm
            f2.ShowDialog();
        
        }

        private void txtAdmin_Click(object sender, EventArgs e)
        {
            if (Level == 1)
            {
                var thread = new Thread(startAdmin);
                // allow UI with ApartmentState.STA though [STAThread] above should give that to you
                thread.TrySetApartmentState(ApartmentState.STA);
                thread.Start();
            }
        }

        private void tmrUsers_Tick(object sender, EventArgs e)
        {
            clients = Server.clientsList;
            List<string> cList = clients.Keys.OfType<string>().ToList();
            lvwClients.Clear();
            ListViewItem listyviewsy = new ListViewItem();
            foreach (string elem in cList)
            {
                lvwClients.Items.Add(new ListViewItem(elem));
            }
        }

    }
}
